/* $RCSFile: AddonNiceMembershipUser.cs $
 * Apache license v2 2011 by Christian Surieux
 * $Source: ?/ADNCRM.Authentication/AddonNiceMembershipUser.cs $
 * $log$
 * Revision 19 2011/01/21 17:51:08  christian.surieux
 *   Recover from Sony move files updated in 11/2010 were not in Source Control
 * Revision 6 2010/08/06 19:56:26  christian.surieux
 *   Added Log to All cs files
 */

using System;
using System.Net;
using System.Diagnostics;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Web.Security;
using System.Web.Services.Protocols;
using System.Globalization;

using AddonNice.Country;
using AddonNice.Settings;
using AddonNice.Security;
using AddonNice.CRMWrapper;
using System.Web.Configuration;

namespace AddonNice.Authentication
{
	public class CrmCustomerId
	{
		private int _typeCode		=	(int)ADNTypeCodes.Contact; // default to contact
		private string _typeName	=	CrmStr.contact; // default to contact
		private Guid _CrmId		    =	Guid.Empty;

		/// <summary>
		/// For serializer
		/// </summary>
		public CrmCustomerId()
		{}

		public CrmCustomerId(int tpCde, Guid Id)
		{
			_typeCode	=	tpCde;
			_typeName	=	CRMUtil.TypeName(typeCode);
			_CrmId		=	Id;
		}

		public CrmCustomerId(string tpnm, Guid Id)
		{
			_typeName	=	tpnm;
			_typeCode	=	(int)CRMUtil.typeCode(tpnm);
			_CrmId		=	Id;
		}

		/// <summary>
		/// CRM Customer typecode
		/// </summary>
		public int typeCode
		{
			get
			{
				return _typeCode;
			}
			set // just here for serializer
			{
				_typeCode   =   value;
			}
		}

		/// <summary>
		/// CRM Customer typename
		/// </summary>
		public string typeName	
		{
			get
			{
				return _typeName;
			}
			set // just here for serializer
			{
				_typeName   =   value;
			}
		}


		/// <summary>
		/// CRM Customer Guid
		/// </summary>
		public Guid CrmId		
		{
			get
			{
				return _CrmId;
			}
			set // just here for serializer
			{
				_CrmId  =   value;
			}
		}

		public DynEntity GetDynUser(CRMWrapperBase wrapper,ResetWrapperHandler fn)
		{
			DynEntity dEnt  =   null;
			switch (typeCode)
			{
				case (int)ADNTypeCodes.SystemUser:
					dEnt    =   DynEntity.GetFromCache<ADNDynSystemUser>(CrmStr.systemuser,wrapper,fn,CrmId);
					break;
				case (int)ADNTypeCodes.Account:
					dEnt    =   DynEntity.GetFromCache<ADNDynAccount>(CrmStr.account,wrapper,fn,CrmId);
					break;
				case (int)ADNTypeCodes.Contact:
					dEnt    =   DynEntity.GetFromCache<ADNDynContact>(CrmStr.contact,wrapper,fn,CrmId);
					break;
				case (int)ADNTypeCodes.Lead:
					dEnt    =   DynEntity.GetFromCache<ADNDynLead>(CrmStr.lead,wrapper,fn,CrmId);
					break;
			}
			return dEnt;
		}
		
		public override string  ToString()
		{
			return string.Format("CrmCustomerId typeCode: {0}, typeName: {1}, CrmId: {2}",typeCode,typeName,CrmId);
		}
	}
	
	
	public class AddonNiceMembershipUser : MembershipUser
	{
		
		CRMWrapperBase Wrapper =    PortalSecurity.Wrapper;

		/// <summary>
		/// install a recent wrapper in dynEntity
		/// </summary>
		static public void ResetWrapper(DynEntity dyn)
		{
			dyn.SetWrapper(AddonNice.Security.PortalSecurity.Wrapper);
		}

		#region Ctor
		
		public AddonNiceMembershipUser(
				string providerName,
				string name,
				object providerUserKey,
				CrmCustomerId Id,
				string email,
				string passwordQuestion,
				string comment,
				bool isApproved,
				bool isLockedOut,
				DateTime creationDate,
				DateTime lastLoginDate,
				DateTime lastActivityDate,
				DateTime lastPasswordChangedDate,
				DateTime lastLockoutDate,
				int portalID,
				string portalAlias,
				Guid wcrmImpersonateID,
				string wcrmImpersonateDomain,string wcrmImpersonateLogin,string wcrmImpersonatePwd,bool wcrmIsCrmUser
			)
			: base(	providerName,
					name,
					providerUserKey,
					email,
					passwordQuestion,
					comment,
					isApproved,
					isLockedOut,
					creationDate,
					lastLoginDate,
					lastActivityDate,
					lastPasswordChangedDate,
					lastLockoutDate)
		{
			if ( SecurityTraceSwitch.Sw.TraceVerbose )
					Trace.WriteLine(string.Format(
				"[V]AddonNiceMembershipUser Ctor providerName: {0}, "+
				"name: {1}, providerUserKey: {2}, CrmCustomerId {3}, email: {4},	passwordQuestion: {5}, comment: {6}, "+
				"isApproved: {7}, isLockedOut: {8},	creationDate: {9}, lastLoginDate: {10}, lastActivityDate: {11}, lastPasswordChangedDate: {12}, "+
				"lastLockoutDate: {13}, portalID: {14}, portalAlias: {15}, crmImpersonateID: {16},CrmImpersonateDomain: {17}, CrmImpersonateLogin: {18}, CrmImpersonatePwd: {19}, CrmIsCrmUser: {20}",
				new object[]{providerName,
				name,
				providerUserKey,
				Id,
				email,
				passwordQuestion,
				comment,
				isApproved,
				isLockedOut,
				creationDate,
				lastLoginDate,
				lastActivityDate,
				lastPasswordChangedDate,
				lastLockoutDate,
				portalID,
				portalAlias,
				wcrmImpersonateID,
				wcrmImpersonateDomain,wcrmImpersonateLogin,wcrmImpersonatePwd,wcrmIsCrmUser}),SecurityTraceSwitch.Sw.Info);
			PortalID			=	portalID;
			_CustomerId         =   Id;
			CrmImpersonateId	=	wcrmImpersonateID;
			PortalAlias			=	portalAlias;
			CrmImpersonateDomain=   wcrmImpersonateDomain;
			CrmImpersonateLogin =   wcrmImpersonateLogin;
			CrmImpersonatePwd   =   wcrmImpersonatePwd;
			CrmIsCrmUser        =   wcrmIsCrmUser;
			CrmEMail            =   email;
			// we do a fast check on roles (only if roles enabled )
			if ( /*( Config.AuthenticationMode == AuthenticationMode.Forms ) &&*/ ( Membership.Provider is AddonNiceMembershipProvider) )
			{
				((AddonNiceMembershipProvider)Membership.Provider).CheckRoles(GetImpersonateUser(Wrapper),this);
			}

		}

		#endregion Ctor
		#region ToString
		public override string ToString()
		{
			return string.Format(
				"AddonNiceMembershipUser Ctor providerName: {0}, "+
				"name: {1}, providerUserKey: {2}, CrmCustomerId {3}, email: {4},	passwordQuestion: {5}, comment: {6}, "+
				"isApproved: {7}, isLockedOut: {8},	creationDate: {9}, lastLoginDate: {10}, lastActivityDate: {11}, lastPasswordChangedDate: {12}, "+
				"lastLockoutDate: {13}, portalID: {14}, portalAlias: {15}, crmImpersonateID: {16},CrmIsCrmUser: {17}",
				new object[]{ProviderName,
				UserName,
				ProviderUserKey,
				_CustomerId,
				Email,
				PasswordQuestion,
				Comment,
				IsApproved,
				IsLockedOut,
				CreationDate,
				LastLoginDate,
				LastActivityDate,
				LastPasswordChangedDate,
				LastLockoutDate,
				PortalID,
				PortalAlias,
				CrmImpersonateId,CrmImpersonateDomain,CrmImpersonateLogin,CrmImpersonatePwd,CrmIsCrmUser});
		}
		#endregion ToString


		#region Membership key values

		string _PortalAlias	=	string.Empty;
		public string PortalAlias
		{
			get { return _PortalAlias; }
			set { _PortalAlias = value; }
		}

		int _PortalID	=	-1;
		public int PortalID
		{
			get { return _PortalID; }
			set { _PortalID = value; }
		}

		public int typeCode
		{
			get { return CustomerId.typeCode; }
		}

		public string typeName
		{
			get { return CustomerId.typeName; }
		}

		public Guid CrmId
		{
			get { return CustomerId.CrmId; }
		}

		private CrmCustomerId _CustomerId =  null;
		public CrmCustomerId CustomerId
		{
			get { return _CustomerId; }
		}
		
		Guid _CrmImpersonateId	=	Guid.Empty;
		public Guid CrmImpersonateId
		{
			get { return _CrmImpersonateId; }
			set { _CrmImpersonateId = value; }
		}

		private string    _CrmImpersonateDomain	=	string.Empty;
		public string CrmImpersonateDomain
		{
			get { return _CrmImpersonateDomain; }
			set { _CrmImpersonateDomain=value; }
		}
		
		private string    _CrmImpersonateLogin	=	string.Empty;
		public string CrmImpersonateLogin
		{
			get { return _CrmImpersonateLogin; }
			set { _CrmImpersonateLogin=value; }
		}
		
		private string    _CrmImpersonatePwd	=	string.Empty;
		public string CrmImpersonatePwd
		{
			get { return _CrmImpersonatePwd; }
			set 
			{
				if ( !string.IsNullOrEmpty(_CrmImpersonatePwd) && 
					!string.IsNullOrEmpty(value) && 
					!_CrmImpersonatePwd.Equals(value) )
					PwdChanged      =   true;
				// we don't accept empty pwds
				if ( !string.IsNullOrEmpty(value) )
					_CrmImpersonatePwd  =   value; 
			}
		}

		
		private bool _CrmIsCrmUser	=	false;
		public bool CrmIsCrmUser
		{
			get { return _CrmIsCrmUser; }
			set 
			{
				_CrmIsCrmUser       =   value; 
			}
		}

		//
		public bool PwdChanged      =   false;

		public override string Comment
		{
				get
				{
					return UserData;
				}
				set
				{
					//base.Comment = value;
				}
		}

		/// <summary>
		/// Special for AddonNiceMembershipProvider
		/// </summary>
		public Guid UserId
		{
			get
			{
				return (Guid)ProviderUserKey;
			}
		}
 

		#endregion Membership key values
		
		#region getting values from crm

		/// <summary>
		/// Update internal impersonate data before a db update for this user
		/// </summary>
		public bool SetImpersonateSystemuser(CRMWrapperBase wWrapper,Guid newId,string newpwd)
		{
			ADNDynSystemUser dynUser        =   DynEntity.GetFromCache<ADNDynSystemUser>(CrmStr.systemuser,wWrapper,ResetWrapper,newId);
			if ( dynUser.Retrieved )
			{
				if (SecurityTraceSwitch.Sw.TraceVerbose)
					Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser SetImpersonateUser domainname: {0}",dynUser.domainname),SecurityTraceSwitch.Sw.Info);
				string domainName           =   dynUser.domainname;
				int idx                     =   domainName.LastIndexOf('\\');
				if (idx != -1)
				{
					string domain           =   domainName.Substring(0, idx);
					string login            =   domainName.Substring(idx + 1);
					if (SecurityTraceSwitch.Sw.TraceVerbose)
						Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser SetImpersonateUser domain: {0}, login: {1}", domain, login), SecurityTraceSwitch.Sw.Info);
					if ( wWrapper.IsUserOk4Crm(domain,login,newpwd) )
					{
						CrmImpersonateId    =   newId;
						CrmImpersonateLogin =   login;
						CrmImpersonatePwd   =   newpwd;
						if (SecurityTraceSwitch.Sw.TraceVerbose)
							Trace.WriteLine( "[V]AddonNiceMembershipUser SetImpersonateUser Credentials OK END.", SecurityTraceSwitch.Sw.Info);
						return true;
					}
				}
			}
			return false;
		}

		public ADNDynSystemUser GetImpersonateUser(CRMWrapperBase wWrapper)
		{
			ADNDynSystemUser dynUser        =   DynEntity.GetFromCache<ADNDynSystemUser>(CrmStr.systemuser,wWrapper,ResetWrapper,CrmImpersonateId);
			if (SecurityTraceSwitch.Sw.TraceVerbose)
						Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser GetImpersonateUser Retrieved: {0}, lastname: {1}", dynUser.Retrieved, dynUser.lastname), SecurityTraceSwitch.Sw.Info);
			return dynUser;
		}
		
		public bool IsAdmin(CRMWrapperBase wWrapper)
		{
			return GetImpersonateUser(wWrapper).IsUserInRoles(Config.CRMAdminRole);
		}

		/* Data are mapped between CRM and AddonNIce according the entity used with the following schema
		 * *********
		 * contact *
		 * *********
			UserFirstName       :   firstname
			UserName            :   lastname
			CrmEmail            :   emailaddress1
			nickname            :   nickname
			Company             :   TDB with parentcustomerid
			SIC                 :   parentcustomerid.sic
			SendNewsletter      :   !donotbulkemail
			-------------- for Bill we use address1
			Address             :   address1_line1 + address1_line2 + address1_line3 if secondaries adresses lines not null
			Zip                 :   address1_postalcode
			City                :   address1_city
			Country             :   address1_country
			County              :   address1_county
			Fax                 :   address1_fax
			Phone               :   address1_telephone1
			-------------- for Ship we use address2
			Address             :   address2_line1 + address2_line2 + address2_line3 if secondaries adresses lines not null
			Zip                 :   address2_postalcode
			City                :   address2_city
			Country             :   address2_country
			County              :   address2_county
			Fax                 :   address2_fax
			Phone               :   address2_telephone1

		 * *********
		 * account *
		 * *********
			UserFirstName       :   string.Empty
			UserName            :   name
			CrmEmail            :   emailaddress1
			nickname            :   name
			Company             :   name
			SIC                 :   sic
			SendNewsletter      :   !donotbulkemail
			-------------- for Bill we use address1
			Address             :   address1_line1 + address1_line2 + address1_line3 if secondaries adresses lines not null
			Zip                 :   address1_postalcode
			City                :   address1_city
			Country             :   address1_country
			County              :   address1_county
			Fax                 :   address1_fax
			Phone               :   address1_telephone1
			-------------- for Ship we use address2
			Address             :   address2_line1 + address2_line2 + address2_line3 if secondaries adresses lines not null
			Zip                 :   address2_postalcode
			City                :   address2_city
			Country             :   address2_country
			County              :   address2_county
			Fax                 :   address2_fax
			Phone               :   address2_telephone1

		 * **********
		 * prospect *
		 * **********
			UserFirstName       :   firstname
			UserName            :   lastname
			CrmEmail            :   emailaddress1
			nickname            :   lastname
			Company             :   companyname
			SIC                 :   string.empty
			SendNewsletter      :   !donotbulkemail
			-------------- for Bill we use address1
			Address             :   address1_line1 + address1_line2 + address1_line3 if secondaries adresses lines not null
			Zip                 :   address1_postalcode
			City                :   address1_city
			Country             :   address1_country
			County              :   address1_county
			Fax                 :   address1_fax
			Phone               :   address1_telephone1
			-------------- for Ship we use address2
			Address             :   address2_line1 + address2_line2 + address2_line3 if secondaries adresses lines not null
			Zip                 :   address2_postalcode
			City                :   address2_city
			Country             :   address2_country
			County              :   address2_county
			Fax                 :   address2_fax
			Phone               :   address2_telephone1
		 * */

		/// <summary>
		/// Maps crm data to internal properties
		/// </summary>
		void MapFields()
		{
			 if ( SecurityTraceSwitch.Sw.TraceVerbose )
				 Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser MapFields BEG DynEntity is null : {0}", _dynEntity == null),SecurityTraceSwitch.Sw.Info);
			// Common values to all entities
			_UserFirstName                  =   string.Empty;
			if ( _dynEntity.ContainsKey(CrmStr.donotbulkemail) )
				_SendNewsletter             =   !_dynEntity.BooleanPropertyValue(CrmStr.donotbulkemail);
			_Company                        =   string.Empty;
			_SIC                            =   string.Empty;
			// This is the Crm Email, it could have been changed so if changed we try to keep synchronized
			// As Crm is sending mails, it is consdered as main source, so if user change mail, we must update crm and membership
			_CrmEMail                       =   _dynEntity.StringPropertyValue(CrmStr.emailaddress1);
			// if we get desynchronized take the nom empty value
			if ( string.IsNullOrEmpty(_CrmEMail) )
				_CrmEMail                   =   Email;
			// -------------- for Bill we use address1
			_BillAddress1                    =   _dynEntity.StringPropertyValue(CrmStr.address1_line1);
			 if ( SecurityTraceSwitch.Sw.TraceVerbose )
				 Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser MapFields mapped address1_line1 : {0}", _BillAddress1),SecurityTraceSwitch.Sw.Info);
			_BillAddress2                    =   _dynEntity.StringPropertyValue(CrmStr.address1_line2);
			 if ( SecurityTraceSwitch.Sw.TraceVerbose )
				 Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser MapFields mapped address1_line2 : {0}", _BillAddress2),SecurityTraceSwitch.Sw.Info);
			_BillAddress3                    =   _dynEntity.StringPropertyValue(CrmStr.address1_line3);
			 if ( SecurityTraceSwitch.Sw.TraceVerbose )
				 Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser MapFields mapped address1_line3 : {0}", _BillAddress3),SecurityTraceSwitch.Sw.Info);
			_BillZip                         =   _dynEntity.StringPropertyValue(CrmStr.address1_postalcode);
			 if ( SecurityTraceSwitch.Sw.TraceVerbose )
				 Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser MapFields mapped address1_postalcode : {0}", _BillZip),SecurityTraceSwitch.Sw.Info);
			_BillCity                        =   _dynEntity.StringPropertyValue(CrmStr.address1_city);
			 if ( SecurityTraceSwitch.Sw.TraceVerbose )
				 Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser MapFields mapped address1_city : {0}", _BillCity),SecurityTraceSwitch.Sw.Info);
			_BillCountry                    =   _dynEntity.StringPropertyValue(CrmStr.address1_country);
			if ( !string.IsNullOrEmpty(_BillCountry) )
				_BillCountryID  =    GetCountryID(_BillCountry);

			 if ( SecurityTraceSwitch.Sw.TraceVerbose )
				 Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser MapFields mapped address1_country : {0}", _BillCountry),SecurityTraceSwitch.Sw.Info);
			_BillCounty                     =   _dynEntity.StringPropertyValue(CrmStr.address1_county);
			 if ( SecurityTraceSwitch.Sw.TraceVerbose )
				 Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser MapFields mapped address1_county : {0}", _BillCounty),SecurityTraceSwitch.Sw.Info);
			if ( !string.IsNullOrEmpty(_BillCountry) && !string.IsNullOrEmpty(_BillCounty) )
				_BillCountyID   = GetCountyID(_BillCountry,_BillCounty);
			_BillFax                         =   _dynEntity.StringPropertyValue(CrmStr.address1_fax);
			 if ( SecurityTraceSwitch.Sw.TraceVerbose )
				 Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser MapFields mapped address1_fax : {0}", _BillFax),SecurityTraceSwitch.Sw.Info);
			_BillPhone                       =   _dynEntity.StringPropertyValue(CrmStr.address1_telephone1);
			 if ( SecurityTraceSwitch.Sw.TraceVerbose )
				 Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser MapFields mapped address1_telephone1 : {0}", _BillPhone),SecurityTraceSwitch.Sw.Info);
			//-------------- for Ship we use address2
			_ShipAddress1               =   _dynEntity.StringPropertyValue(CrmStr.address2_line1);
			 if ( SecurityTraceSwitch.Sw.TraceVerbose )
				 Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser MapFields mapped address2_line1 : {0}", _ShipAddress1),SecurityTraceSwitch.Sw.Info);
			_ShipAddress2               =   _dynEntity.StringPropertyValue(CrmStr.address2_line2);
			 if ( SecurityTraceSwitch.Sw.TraceVerbose )
				 Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser MapFields mapped address2_line2 : {0}", _ShipAddress2),SecurityTraceSwitch.Sw.Info);
			_ShipAddress3               =   _dynEntity.StringPropertyValue(CrmStr.address2_line3);
			 if ( SecurityTraceSwitch.Sw.TraceVerbose )
				 Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser MapFields mapped address2_line3 : {0}", _ShipAddress3),SecurityTraceSwitch.Sw.Info);
			_ShipZip                    =   _dynEntity.StringPropertyValue(CrmStr.address2_postalcode);
			 if ( SecurityTraceSwitch.Sw.TraceVerbose )
				 Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser MapFields mapped address2_postalcode : {0}", _ShipZip),SecurityTraceSwitch.Sw.Info);
			_ShipCity                   =   _dynEntity.StringPropertyValue(CrmStr.address2_city);
			 if ( SecurityTraceSwitch.Sw.TraceVerbose )
				 Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser MapFields mapped address2_city : {0}", _ShipCity),SecurityTraceSwitch.Sw.Info);
			_ShipCountry                =   _dynEntity.StringPropertyValue(CrmStr.address2_country);
			if ( !string.IsNullOrEmpty(_ShipCountry) )
				_ShipCountryID  =    GetCountryID(_ShipCountry);
			 if ( SecurityTraceSwitch.Sw.TraceVerbose )
				 Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser MapFields mapped address2_country : {0}", _ShipCountry),SecurityTraceSwitch.Sw.Info);
			_ShipCounty                =   _dynEntity.StringPropertyValue(CrmStr.address2_county);
			if ( !string.IsNullOrEmpty(_ShipCountry) && !string.IsNullOrEmpty(_ShipCounty) )
				_ShipCountyID   = GetCountyID(_ShipCountry,_ShipCounty);
			 if ( SecurityTraceSwitch.Sw.TraceVerbose )
				 Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser MapFields mapped address2_county : {0}", _ShipCounty),SecurityTraceSwitch.Sw.Info);
			_ShipFax                    =   _dynEntity.StringPropertyValue(CrmStr.address2_fax);
			 if ( SecurityTraceSwitch.Sw.TraceVerbose )
				 Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser MapFields mapped address2_fax : {0}", _ShipFax),SecurityTraceSwitch.Sw.Info);
			_ShipPhone                  =   _dynEntity.StringPropertyValue(CrmStr.address2_telephone1);
			 if ( SecurityTraceSwitch.Sw.TraceVerbose )
				 Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser MapFields mapped address2_telephone1 : {0}", _ShipPhone),SecurityTraceSwitch.Sw.Info);

			switch (typeCode)
			{
				// account 
				case 1:
					{
						_nickname           = _dynEntity.StringPropertyValue(CrmStr.name);
						_Company            = _dynEntity.StringPropertyValue(CrmStr.name);
						_SIC                = _dynEntity.StringPropertyValue(CrmStr.sic);
						break;
					}
				// contact 
				case 2:
					{
						_UserFirstName      = _dynEntity.StringPropertyValue(CrmStr.firstname);
						_nickname           = _dynEntity.StringPropertyValue(CrmStr.nickname);
						// if retrieving also parentaccounts, get values from here
						if ( SecurityTraceSwitch.Sw.TraceVerbose )
							Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser mapFields _dynAccount null: {0}.",_dynAccount == null ),SecurityTraceSwitch.Sw.Info);
						if ( _dynAccount != null )
						{
							if ( _dynEntity.ContainsKey(CrmStr.parentcustomerid) )
							{
								_dynAccount.accountid   = _dynEntity.CustomerPropertyValue(CrmStr.parentcustomerid);
								if ( _dynAccount.Retrieve() )
								{
									_Company    =   _dynAccount.name;
									_SIC        =   _dynAccount.sic;
								}
							}
						}
						break;
					}

				// prospect 
				case 4:
					_UserFirstName          = _dynEntity.StringPropertyValue(CrmStr.firstname);
					_nickname               = _dynEntity.StringPropertyValue(CrmStr.lastname);
					_Company                = _dynEntity.StringPropertyValue(CrmStr.companyname);
					break;
			}
		}

		/// <summary>
		/// Similar to EnsureCrmDataLaded but don't force loading
		/// </summary>
		public bool IsInfoLoadedFromCrm()
		{
			return _dynEntity != null;
		}

		/// <summary>
		/// If corresponding Crm entity is not loaded from crm, get it
		/// </summary>
		public bool EnsureCrmDataLoaded()
		{
			if ( dynEntity == null )
				return false;
			return true;
		}

		public void RefreshCrmData()
		{
			_dynEntity = null;
			EnsureCrmDataLoaded();
		}

		public bool ShouldAutoCreateParentAccount()
		{
			return ((Membership.Provider is AddonNiceMembershipProvider) &&
					 ((AddonNiceMembershipProvider)Membership.Provider).AutoCreateParentAccount);
		}


		public void UpdateCrmData()
		{
			UpdateCrmData(ShouldAutoCreateParentAccount());
		}
		
		public void UpdateCrmData(bool AutoCreateParentAccount)
		{
			if (_dynEntity == null)
			{
				switch (typeCode)
				{
					// account 
					case 1:
					{
						_dynEntity  =   new ADNDynAccount(Wrapper,CustomerId.CrmId);
						break;
					}
					// contact 
					case 2:
					{
						_dynEntity  =   new ADNDynContact(Wrapper,CustomerId.CrmId);
						break;
					}

					// prospect 
					case 4:
					{
						_dynEntity  =   new ADNDynLead(Wrapper,CustomerId.CrmId);
						break;
					}
				}
			}
			if ( SecurityTraceSwitch.Sw.TraceVerbose )
				Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser UpdateCrmData BEG at : {0}", DateTime.Now),SecurityTraceSwitch.Sw.Info);
			try
			{
				_dynEntity.AddStringProperty(CrmStr.emailaddress1, _CrmEMail);
				_dynEntity.AddBooleanProperty(CrmStr.donotbulkemail, !_SendNewsletter);
				// -------------- for Bill we use address1
				// same default picklist as in address is not installed in account/contact _dynEntity.AddPicklistProperty(CrmStr.address1_addresstypecode, 1);
				_dynEntity.AddStringProperty(CrmStr.address1_line1, _BillAddress1);
				_dynEntity.AddStringProperty(CrmStr.address1_line2, _BillAddress2);
				_dynEntity.AddStringProperty(CrmStr.address1_line3, _BillAddress3);
				_dynEntity.AddStringProperty(CrmStr.address1_postalcode, _BillZip);
				_dynEntity.AddStringProperty(CrmStr.address1_city, _BillCity);
				_dynEntity.AddStringProperty(CrmStr.address1_country, _BillCountry);
				_dynEntity.AddStringProperty(CrmStr.address1_county, _BillCounty);
				_dynEntity.AddStringProperty(CrmStr.address1_fax, _BillFax);
				_dynEntity.AddStringProperty(CrmStr.address1_telephone1, _BillPhone);
				//-------------- for Ship we use address2
				// same default picklist as in address is not installed in account/contact _dynEntity.AddPicklistProperty(CrmStr.address2_addresstypecode, 2);
				_dynEntity.AddStringProperty(CrmStr.address2_line1, _ShipAddress1);
				_dynEntity.AddStringProperty(CrmStr.address2_line2, _ShipAddress2);
				_dynEntity.AddStringProperty(CrmStr.address2_line3, _ShipAddress3);
				_dynEntity.AddStringProperty(CrmStr.address2_postalcode, _ShipZip);
				_dynEntity.AddStringProperty(CrmStr.address2_city, _ShipCity);
				_dynEntity.AddStringProperty(CrmStr.address2_country, _ShipCountry);
				_dynEntity.AddStringProperty(CrmStr.address2_county, _ShipCounty);
				_dynEntity.AddStringProperty(CrmStr.address2_fax, _ShipFax);
				_dynEntity.AddStringProperty(CrmStr.address2_telephone1, _ShipPhone);

				switch (typeCode)
				{
					// account 
					case 1:
						{
							// already there _UserName           = _dynEntity.AddStringProperty("name");
							//_dynEntity.PicklistPropertyNameValue("industrycode");
							break;
						}
					// contact 
					case 2:
						{
							// should we try to create parent account
							if (AutoCreateParentAccount && !string.IsNullOrEmpty(_Company))
							{
								if ( SecurityTraceSwitch.Sw.TraceVerbose )
									Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser UpdateCrmData update or create account: {0}", _Company),SecurityTraceSwitch.Sw.Info);
								bool created            =   false;
								ADNDynAccount    acc    =   Wrapper.Util.FindAccountByName(_Company,true,ref created);
								if ( SecurityTraceSwitch.Sw.TraceVerbose )
									Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser UpdateCrmData account: {0}, created: {1}", _Company,created),SecurityTraceSwitch.Sw.Info);
								if (acc != null)
								{
									if (!_SIC.Equals(acc.sic))
									{
										if ( SecurityTraceSwitch.Sw.TraceVerbose )
											Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser UpdateCrmData account: {0}, update sic: {1}", _Company,_SIC),SecurityTraceSwitch.Sw.Info);
										acc.sic     =   _SIC;
										acc.adminUpdate();
									}
									Guid newAccId                                   =   acc.PrimaryKeyGuidValue;
									((ADNDynContact)_dynEntity).parentcustomerid     =   newAccId;
									if ( SecurityTraceSwitch.Sw.TraceVerbose )
										Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser UpdateCrmData set in parentcustomerid accountid: {0}", newAccId),SecurityTraceSwitch.Sw.Info);
								}
							}
							_dynEntity.AddStringProperty(CrmStr.firstname, _UserFirstName);
							_dynEntity.AddStringProperty(CrmStr.nickname, _nickname);
							break;
						}
					// prospect 
					case 4:
						_dynEntity.AddStringProperty(CrmStr.firstname, _UserFirstName);
						_dynEntity.AddStringProperty(CrmStr.companyname, _Company);
						break;
				}
				if ( SecurityTraceSwitch.Sw.TraceVerbose )
					Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser UpdateCrmData before AdminUpdate UserName: {0}", UserName),SecurityTraceSwitch.Sw.Info);
				_dynEntity.adminUpdate();
				if ( SecurityTraceSwitch.Sw.TraceVerbose )
					Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser UpdateCrmData AdminUpdate OK UserName: {0}", UserName),SecurityTraceSwitch.Sw.Info);
				// If email has changed for crm, change it in Provider
				if (!string.IsNullOrEmpty(Email) && Email != CrmEMail)
				{
					if ( SecurityTraceSwitch.Sw.TraceVerbose )
						Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser UpdateCrmData Update Email UserName: {0}", UserName),SecurityTraceSwitch.Sw.Info);
					((AddonNiceMembershipProvider)Membership.Provider).UpdateEmail(this);
				}
				if (!string.IsNullOrEmpty(NewQuestion) && !string.IsNullOrEmpty(NewQuestion) && !string.IsNullOrEmpty(NewAnswer))
				{
					if ( SecurityTraceSwitch.Sw.TraceVerbose )
						Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser UpdateCrmData Update Pwd/Question/Answer UserName: {0}", UserName),SecurityTraceSwitch.Sw.Info);
					((AddonNiceMembershipProvider)Membership.Provider).ChangePasswordQuestionAndAnswer(UserName,NewPwd,NewQuestion, NewAnswer);
				}
			}
			catch (Exception ex)
			{
				if ( SecurityTraceSwitch.Sw.TraceError )
					Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser UpdateCrmData ex : {0}", ex),SecurityTraceSwitch.Sw.Info);
				throw;
			}
		}

		ADNDynAccount _dynAccount    =   null;
		DynEntity _dynEntity        =   null;
		/// <summary>
		/// Contains corresponding Crm datas, loaded as soon as data is requested
		/// </summary>
		public DynEntity dynEntity
		{
			get
			{
				if (_dynEntity == null)
				{
					if ( SecurityTraceSwitch.Sw.TraceVerbose )
						Trace.WriteLine( "[V]AddonNiceMembershipUser dynEntity GET BEG.",SecurityTraceSwitch.Sw.Info);
					try
					{
						switch (typeCode)
						{
							// account 
							case 1:
							{
								_dynEntity  =   DynEntity.GetFromCache<ADNDynAccount>(CrmStr.account,Wrapper,ResetWrapper,CustomerId.CrmId);
								break;
							}
							// contact 
							case 2:
							{
								_dynEntity  =   DynEntity.GetFromCache<ADNDynContact>(CrmStr.contact,Wrapper,ResetWrapper,CustomerId.CrmId);
								if (ShouldAutoCreateParentAccount())
								{
									if ( SecurityTraceSwitch.Sw.TraceVerbose )
										Trace.WriteLine( "[V]AddonNiceMembershipUser dynEntity GET creating dynAccount.",SecurityTraceSwitch.Sw.Info);
									_dynAccount     =   new ADNDynAccount(Wrapper, Guid.Empty);
								}
								break;
							}

							// prospect 
							case 4:
							{
								_dynEntity  =   DynEntity.GetFromCache<ADNDynLead>(CrmStr.lead,Wrapper,ResetWrapper,CustomerId.CrmId);
								break;
							}
						}
						if (_dynEntity.Retrieved)
							MapFields();
					}
					catch (Exception ex)
					{
						string msg  =   string.Format("[E]AddonNiceMembershipUser dynEntity GET ex: {0}", ex);
						if ( SecurityTraceSwitch.Sw.TraceError )
							Trace.WriteLine( msg,SecurityTraceSwitch.Sw.Info);
						_dynEntity  =   null;
						throw new CRMWrapperException(msg, ex);
					}
				}
				if ( SecurityTraceSwitch.Sw.TraceVerbose )
					Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser dynEntity GET End Ok CustomerId: {0}", CustomerId),SecurityTraceSwitch.Sw.Info);
				return _dynEntity;
			}
		}

		#endregion getting values from crm

		#region properties from crm

		#region generic methods
		public string GetStringValue(string key)
		{
			EnsureCrmDataLoaded();
			return dynEntity.StringPropertyValue(key);
		}
		
		public int GetIntValue(string key)
		{
			EnsureCrmDataLoaded();
			return dynEntity.NumberPropertyValue(key);
		}
		
		public decimal GetMoneyValue(string key)
		{
			EnsureCrmDataLoaded();
			return dynEntity.MoneyPropertyValue(key);
		}
		public string GetDateTimeValue(string key)
		{
			EnsureCrmDataLoaded();
			return dynEntity.DateTimePropertyValue(key);
		}
		public Guid GetKeyValue(string key)
		{
			EnsureCrmDataLoaded();
			return dynEntity.KeyPropertyValue(key);
		}

		internal string GetCountryID(string CountryName)
		{
			if (!string.IsNullOrEmpty(CountryName))
			{
				try
				{
					CountryInfo country = new CountryInfo(CountryName);
					if (SecurityTraceSwitch.Sw.TraceVerbose)
						Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser GetCountryID CountryName: {0}, CountryID: {1}",
							CountryName, country.ThreeLetterISOCountryName), SecurityTraceSwitch.Sw.Info);
					return country.ThreeLetterISOCountryName;
				}
				catch (Exception ex)
				{
					if (SecurityTraceSwitch.Sw.TraceError)
						Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]AddonNiceMembershipUser GetCountryID CountryName: {0}, ex: {1}", CountryName, ex), SecurityTraceSwitch.Sw.Info);
				}
			}
			if (SecurityTraceSwitch.Sw.TraceVerbose)
				Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser GetCountryID NOT FOUND CountryName: {0}", CountryName), SecurityTraceSwitch.Sw.Info);
			return string.Empty;
		}

		internal string GetCountyID(string CountryName, string CountyName)
		{
			if (!string.IsNullOrEmpty(CountryName))
			{
				try
				{
					CountryInfo country = new CountryInfo(CountryName);
					CountryInfo county = country.GetChildCountryInfo(CountyName);
					if (SecurityTraceSwitch.Sw.TraceVerbose)
						Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser GetCountyID CountryName: {0}, CountyName: {1}, county: {2}", 
							CountryName, CountyName, county != null), SecurityTraceSwitch.Sw.Info);
					if ( county != null )
						return county.EnglishName;
				}
				catch (Exception ex)
				{
					if (SecurityTraceSwitch.Sw.TraceError)
						Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]AddonNiceMembershipUser GetCountyID CountryName: {0}, CountyName: {1}, ex: {2}",
							CountryName, CountyName, ex), SecurityTraceSwitch.Sw.Info);
				}
			}
			if (SecurityTraceSwitch.Sw.TraceVerbose)
				Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceMembershipUser GetCountyID NOT FOUND CountryName: {0}, CountyName: {1}", CountryName, CountyName), SecurityTraceSwitch.Sw.Info);
			return string.Empty;
		}

		
		#endregion generic methods
		
		#region properties
		string _UserFirstName          =   string.Empty;
		public string UserFirstName
		{
			get
			{
				EnsureCrmDataLoaded();
				return _UserFirstName;
			}
			set
			{
				_UserFirstName  =   value;
			}
		}

		
		bool _SendNewsletter           =   true;
		public bool SendNewsletter
		{
			get
			{
				EnsureCrmDataLoaded();
				return _SendNewsletter;
			}
			set
			{
				_SendNewsletter  =   value;
			}
		}

		string _Company                =   string.Empty;
		public string Company                
		{
			get
			{
				EnsureCrmDataLoaded();
				return _Company;
			}
			set
			{
				_Company  =   value;
			}
		}

		string _SIC                   =   string.Empty;
		// Standart Industrical Classification code 
		public string SIC                   
		{
			get
			{
				EnsureCrmDataLoaded();
				return _SIC;
			}
			set
			{
				_SIC  =   value;
			}
		}

		string _nickname = string.Empty;
		public string nickname 
		{
			get
			{
				EnsureCrmDataLoaded();
				return _nickname ;
			}
			set
			{
				_nickname  =   value;
			}
		}

		string _CrmEMail = string.Empty;
		public string CrmEMail
		{
			get
			{
				EnsureCrmDataLoaded();
				return _CrmEMail;
			}
			set
			{
				_CrmEMail  =   value;
			}
		}

		#region Used by AddonNiceUser when updating

		string NewQuestion = string.Empty;
		public void SetNewQuestion(string val)
		{
			NewQuestion  =   val;
		}
		
		string NewAnswer = string.Empty;
		public void SetNewAnswer(string val)
		{
			NewAnswer  =   val;
		}
		
		// Keep it this form in order to be displed and entered in grid for AdminUsers
		string _NewPwd = string.Empty;
		string NewPwd 
		{
			get
			{
				return _NewPwd;
			}
			set
			{
				_NewPwd  =   value;
			}
		}

		public void SetNewPwd(string  val)
		{
			NewPwd  =   val;
		}

		#endregion Used by AddonNiceUser when updating

		// -------------- for Bill we use address1
		string _BillAddress1             =   string.Empty;
		public string BillAddress1             
		{
			get
			{
				EnsureCrmDataLoaded();
				return _BillAddress1;
			}
			set
			{
				_BillAddress1  =   value;
			}
		}

		string _BillAddress2             =   string.Empty;
		public string BillAddress2             
		{
			get
			{
				EnsureCrmDataLoaded();
				return _BillAddress2;
			}
			set
			{
				_BillAddress2  =   value;
			}
		}

		string _BillAddress3             =   string.Empty;
		public string BillAddress3             
		{
			get
			{
				EnsureCrmDataLoaded();
				return _BillAddress3;
			}
			set
			{
				_BillAddress3  =   value;
			}
		}

		string _BillZip                 =   string.Empty;
		public string BillZip                 
		{
			get
			{
				EnsureCrmDataLoaded();
				return _BillZip;
			}
			set
			{
				_BillZip  =   value;
			}
		}

		string _BillCity                =   string.Empty;
		public string BillCity                
		{
			get
			{
				EnsureCrmDataLoaded();
				return _BillCity;
			}
			set
			{
				_BillCity  =   value;
			}
		}

		string _BillCountry = string.Empty;
		public string BillCountry
		{
			get
			{
				EnsureCrmDataLoaded();
				return _BillCountry;
			}
			set
			{
				_BillCountry    =   value;
				_BillCountryID  =    GetCountryID(_BillCountry);
			}
		}

		string _BillCountryID = string.Empty;
		public string BillCountryID
		{
			get
			{
				return _BillCountryID;
			}
			set
			{
				_BillCountryID = value;
			}
		}

		string _BillCounty = string.Empty;
		public string BillCounty
		{
			get
			{
				EnsureCrmDataLoaded();
				return _BillCounty;
			}
			set
			{
				_BillCountyID   = GetCountyID(_BillCountry,value);
				if ( !string.IsNullOrEmpty(_BillCountyID) )
					_BillCounty     = value;
			}
		}

		string _BillCountyID = string.Empty;
		public string BillCountyID
		{
			get
			{
				EnsureCrmDataLoaded();
				return _BillCountyID;
			}
		}

		string _BillFax                 =   string.Empty;
		public string BillFax                 
		{
			get
			{
				EnsureCrmDataLoaded();
				return _BillFax;
			}
			set
			{
				_BillFax  =   value;
			}
		}

		string _BillPhone               =   string.Empty;
		public string BillPhone               
		{
			get
			{
				EnsureCrmDataLoaded();
				return _BillPhone;
			}
			set
			{
				_BillPhone  =   value;
			}
		}

		//-------------- for Ship we use address2
		string _ShipAddress1                =   string.Empty;
		public string ShipAddress1                
		{
			get
			{
				EnsureCrmDataLoaded();
				return _ShipAddress1;
			}
			set
			{
				_ShipAddress1  =   value;
			}
		}

		string _ShipAddress2                =   string.Empty;
		public string ShipAddress2                
		{
			get
			{
				EnsureCrmDataLoaded();
				return _ShipAddress2;
			}
			set
			{
				_ShipAddress2  =   value;
			}
		}

		string _ShipAddress3                =   string.Empty;
		public string ShipAddress3                
		{
			get
			{
				EnsureCrmDataLoaded();
				return _ShipAddress3;
			}
			set
			{
				_ShipAddress3  =   value;
			}
		}

		string _ShipZip                    =   string.Empty;
		public string ShipZip                    
		{
			get
			{
				EnsureCrmDataLoaded();
				return _ShipZip;
			}
			set
			{
				_ShipZip  =   value;
			}
		}

		string _ShipCity                   =   string.Empty;
		public string ShipCity                   
		{
			get
			{
				EnsureCrmDataLoaded();
				return _ShipCity;
			}
			set
			{
				_ShipCity  =   value;
			}
		}

		string _ShipCountry = string.Empty;
		public string ShipCountry
		{
			get
			{
				EnsureCrmDataLoaded();
				return _ShipCountry;
			}
			set
			{
				_ShipCountry = value;
				_ShipCountryID = GetCountryID(_ShipCountry);
			}
		}

		string _ShipCountryID = string.Empty;
		public string ShipCountryID              
		{
			get
			{
				EnsureCrmDataLoaded();
				return _ShipCountryID;
			}
			set
			{
				_ShipCountryID  =   value;
			}
		}

		string _ShipCounty = string.Empty;
		public string ShipCounty
		{
			get
			{
				EnsureCrmDataLoaded();
				return _ShipCounty;
			}
			set
			{
				_ShipCountyID   = GetCountyID(_ShipCountry,value);
				if ( !string.IsNullOrEmpty(_ShipCountyID) )
					_ShipCounty = value;
			}
		}

		string _ShipCountyID = string.Empty;
		public string ShipCountyID
		{
			get
			{
				EnsureCrmDataLoaded();
				return _ShipCountyID;
			}
		}

		string _ShipFax                    =   string.Empty;
		public string ShipFax                    
		{
			get
			{
				EnsureCrmDataLoaded();
				return _ShipFax;
			}
			set
			{
				_ShipFax  =   value;
			}
		}

		string _ShipPhone                  =   string.Empty;
		public         string ShipPhone
		{
			get
			{
				EnsureCrmDataLoaded();
				return _ShipPhone;
				}
			set
			{
				_ShipPhone  =   value;
			}
		}



		#endregion properties

		#endregion properties from crm

		#region public methods
		public string UserData
		{
			get
			{
				return string.Format("{0}|{1}|{2}|{3}|{4}|{5}|{6}|{7}|{8}|{9}", new object[] 
							{1,UserName,"Forms",
							CustomerId.CrmId,typeCode,ProviderUserKey,
							CrmImpersonateId,EncodeSpecialCars(CrmImpersonateDomain,false),EncodeSpecialCars(CrmImpersonateLogin,false),EncodeSpecialCars(CrmImpersonatePwd,true) });
			}
		}

		string EncodeSpecialCars(string str, bool isPwd)
		{
			return Convert.ToBase64String(Encoding.ASCII.GetBytes(str));    
			//return str.Replace("|","\\");
		}


		string DecodeSpecialCars(string str, bool isPwd)
		{
			return Encoding.ASCII.GetString(Convert.FromBase64String(str));
			//return str.Replace("\\","|");
		}
		#endregion publc methods
		}
}
